Feito por Lucas Lopes - 08/03/2022
A empresa Bagy está procurando por maneiras de identificar os clientes-chave e fatores de sucesso de sua plataforma com o objetivo de identificar padrões e replicar ações para toda a base de clientes. Para isso será preciso analisar a base de pedidos dos lojistas, ou seja, a base de dados de compras efetuadas em sites que utilizam a plataforma Bagy E-commerce internacionalmente.
Com esses dados em mãos, poderemos propor ações que ajudem os lojistas a venderem mais e por consequência ficarem mais satisfeitos com a plataforma.
Importando as bibliotecas que iremos utilizar ao decorrer da análise.
import pandas as pd
from pandasql import sqldf
import matplotlib.pyplot as plt
import seaborn as sns
import plotly.express as px
import warnings
import os
import locale
import datetime
from scipy.stats import spearmanr
warnings.filterwarnings('ignore')
Importando a base de dados de pedidos do e-commerce com a função pd.read_csv() da biblioteca pandas.
Você pode encontrar os dados disponibilizados pela empresa Bagy clicando neste link.
pedidos = pd.read_csv('dados/teste_dados_ecommerce.csv', sep=';')
A primeira coisa a se fazer é verificar os tipos dos dados que estamos trabalhando (texto, inteiros, reais e etc..).
pedidos.info()
<class 'pandas.core.frame.DataFrame'> RangeIndex: 541909 entries, 0 to 541908 Data columns (total 9 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 InvoiceNo 541909 non-null object 1 StoreId 541909 non-null int64 2 StockCode 541909 non-null object 3 Description 540455 non-null object 4 Quantity 541909 non-null int64 5 InvoiceDate 541909 non-null object 6 UnitPrice 541909 non-null float64 7 CustomerID 406829 non-null float64 8 Country 541909 non-null object dtypes: float64(2), int64(2), object(5) memory usage: 37.2+ MB
Será necessário alterar o tipo dos dados das colunas StoreId para o tipo string e InvoiceDate para o tipo datetime. Isto nos trará facilidades ao trabalhar com relacionamento entre tabelas e operações com datas mais a frente.
pedidos['StoreId'] = pedidos['StoreId'].astype('str')
pedidos['InvoiceDate'] = pd.to_datetime(pedidos['InvoiceDate'], infer_datetime_format=True)
Agora, vamos verificar se temos valores ausentes no conjunto de dados. Para isto, utilizamos o comando pd.isna e somamos o vetor de boleanos que é retornado.
pd.isna(pedidos).sum()
InvoiceNo 0 StoreId 0 StockCode 0 Description 1454 Quantity 0 InvoiceDate 0 UnitPrice 0 CustomerID 135080 Country 0 dtype: int64
Acima, podemos ver que temos valores ausentes apenas nas colunas Description e CustomerID.
Existem muitas técnicas para tratamento de valores ausentes, porém não faremos nada a respeito destes valores nesta análise, pois eles não afetarão as respostas que pretendemos encontrar.
Abaixo, vamos utilizar o comando pd.shape para verificar a quantidade de linhas e colunas do nosso conjunto de dados.
Podemos ver que o conjunto de dados de pedidos possui 541909 observações (linhas) e 9 variáveis (colunas).
pedidos.shape
(541909, 9)
Utilizaremos o comando pd.describe() para verificar as estatísticas descritivas do conjunto de dados como média, desvio padrão e etc..
pedidos.describe()
| Quantity | UnitPrice | CustomerID | |
|---|---|---|---|
| count | 541909.000000 | 541909.000000 | 406829.000000 |
| mean | 9.552250 | 4.611114 | 15287.690570 |
| std | 218.081158 | 96.759853 | 1713.600303 |
| min | -80995.000000 | -11062.060000 | 12346.000000 |
| 25% | 1.000000 | 1.250000 | 13953.000000 |
| 50% | 3.000000 | 2.080000 | 15152.000000 |
| 75% | 10.000000 | 4.130000 | 16791.000000 |
| max | 80995.000000 | 38970.000000 | 18287.000000 |
Finalmente, vamos visualizar uma parte do nosso conjunto de dados utilizado o comando pd.head()
pedidos.head(3)
| InvoiceNo | StoreId | StockCode | Description | Quantity | InvoiceDate | UnitPrice | CustomerID | Country | |
|---|---|---|---|---|---|---|---|---|---|
| 0 | 536365 | 11 | 85123A | WHITE HANGING HEART T-LIGHT HOLDER | 6 | 2010-12-01 08:26:00 | 2.55 | 17850.0 | United Kingdom |
| 1 | 536365 | 9 | 71053 | WHITE METAL LANTERN | 6 | 2010-12-01 08:26:00 | 3.39 | 17850.0 | United Kingdom |
| 2 | 536365 | 17 | 84406B | CREAM CUPID HEARTS COAT HANGER | 8 | 2010-12-01 08:26:00 | 2.75 | 17850.0 | United Kingdom |
Agora chegou a hora de fazer a análise exploratória dos dados, hora de fazer perguntas e encontrar as respostas.
Abaixo, vamos criar a coluna TotalFaturamento que será a multiplicação dos valores das colunas Quantity e UnitPrice.
pedidos['TotalFaturamento'] = pedidos['Quantity'] * pedidos['UnitPrice']
Com a coluna TotalFaturamento criada, vamos fazer o cálculo do volume de itens vendidos e do valor total vendido. Para isto utilizaremos a função pd.groupby() da biblioteca pandas.
top_10_lojas = pedidos.groupby(['StoreId'], as_index=False).sum()[['StoreId', 'Quantity','TotalFaturamento']]
O próximo passo é ordenar a tabela gerada em ordem decrescente de acordo com os valores de faturamento por meio da função pd.sort_values() e filtrar apenas as 10 primeiras linhas da tabela.
top_10_lojas.sort_values(by='TotalFaturamento', ascending=False, inplace=True, ignore_index=True)
top_10_lojas = top_10_lojas[0:10]
top_10_lojas
| StoreId | Quantity | TotalFaturamento | |
|---|---|---|---|
| 0 | 17 | 337514 | 659675.740 |
| 1 | 4 | 350583 | 607875.170 |
| 2 | 13 | 266709 | 525823.970 |
| 3 | 5 | 251249 | 505066.590 |
| 4 | 15 | 268690 | 504586.530 |
| 5 | 16 | 259878 | 501436.810 |
| 6 | 9 | 271067 | 494288.550 |
| 7 | 2 | 241355 | 493832.540 |
| 8 | 1 | 236687 | 488837.071 |
| 9 | 3 | 245406 | 488437.800 |
Acima, podemos verificar as 10 lojas com maior faturamento em pedidos.
Como não temos os nomes das lojas, vamos substituir os valores da coluna StoreId por nomes genéricos.
Exemplo: Loja 1, Loja 2 e por ai vai..
lojas = ['Loja ' + str(top_10_lojas['StoreId'][i]) for i in top_10_lojas.index]
top_10_lojas['StoreId'] = lojas
Aqui, definiremos um dicionário de cores para construção dos gráficos ao decorrer da análise.
cores = {'branco':'#FFFFFF', 'rosa':'#F93D8A', 'roxo':'#3C0877', 'verde':'#00B00F', 'preto':'#232323'}
Chegou o momento de plotar o primeiro gráfico para responder a primeira pergunta. Os gráficos serão construídos utilizando a biblioteca plotly.express(). Para entender como funcionam os parâmetros utilizados para a construção dos gráficos, recomendo uma leitura mais aprofundada da Documentação Plotly Express.
fig = px.bar(top_10_lojas, y='TotalFaturamento', x='StoreId',
text='TotalFaturamento', labels={'TotalFaturamento':'Faturamento Total',
'StoreId':'Lojas'}, height=500)
fig.update_traces(texttemplate='%{text:.2s}',textposition='outside',
marker_color=cores['rosa'], marker_line=dict(width=0.8, color=cores['roxo']))
fig.update_yaxes(color=cores['roxo'], linecolor=cores['roxo'])
fig.update_xaxes(color=cores['roxo'], linecolor=cores['roxo'])
fig.update_layout(uniformtext_minsize=10, uniformtext_mode='hide',
title='Top 10 Das Lojas Com Maior Faturamento', title_x=0.5,
plot_bgcolor=cores['branco'], modebar_activecolor=cores['rosa'],
font_color=cores['preto'], title_font_color=cores['roxo'],
legend_title_font_color=cores['verde'])
fig.show()
Esses produtos certamente representam grande parte do faturamento da empresa, portanto, as ações de vendas devem ser direcionadas para manter o Top 10 de vendas. Nesse contexto, faz sentido investigar, para cada loja, alguns pontos como:
Criaremos a coluna InvoiceMonth para armazenar o mês do pedido de acordo com os valores de data da coluna InvoiceDate
.
pedidos['InvoiceMonth'] = pedidos['InvoiceDate'].dt.month
Podemos ver abaixo, que a coluna InvoiceMonth, já faz parte do nosso conjunto de dados. Utilizaremos esta coluna para fazer o cálculo do ticket mensal.
pedidos.head(3)
| InvoiceNo | StoreId | StockCode | Description | Quantity | InvoiceDate | UnitPrice | CustomerID | Country | TotalFaturamento | InvoiceMonth | |
|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 536365 | 11 | 85123A | WHITE HANGING HEART T-LIGHT HOLDER | 6 | 2010-12-01 08:26:00 | 2.55 | 17850.0 | United Kingdom | 15.30 | 12 |
| 1 | 536365 | 9 | 71053 | WHITE METAL LANTERN | 6 | 2010-12-01 08:26:00 | 3.39 | 17850.0 | United Kingdom | 20.34 | 12 |
| 2 | 536365 | 17 | 84406B | CREAM CUPID HEARTS COAT HANGER | 8 | 2010-12-01 08:26:00 | 2.75 | 17850.0 | United Kingdom | 22.00 | 12 |
Nosso próximo passo é calcular a média da coluna TotalFaturamento, agrupando os valores por mês. Assim, obteremos os valores do ticket médio mensal dos pedidos.
ticket_medio = pedidos.groupby(['InvoiceMonth'], as_index=False).mean()[['InvoiceMonth', 'TotalFaturamento']]
ticket_medio.rename(columns={'InvoiceMonth':'Mês', 'TotalFaturamento':'Ticket Médio'}, inplace=True)
Vamos substituir os valores numéricos dos meses na coluna Mês pelos nomes dos meses. Para esse fim, vamos utilizar a função setlocale() da biblioteca locale .
locale.setlocale(locale.LC_ALL, 'pt_BR.utf8')
meses = []
for i in ticket_medio['Mês']:
datetime_object = datetime.datetime.strptime(str(i), "%m")
meses.append(datetime_object.strftime("%b"))
Já temos uma lista com os nomes dos meses em Português, basta substituir os valores da coluna Mês
ticket_medio['Mês'] = meses
Neste momento, já temos tudo que precisamos para plotar o gráfico com os valores do ticket mensal médio. Em caso de dúvidas sobre o código abaixo consulte a Documentação Plotly Express.
fig = px.line(ticket_medio, x="Mês", y="Ticket Médio", text="Ticket Médio", height=400)
fig.update_yaxes(color=cores['roxo'], showgrid=True,
gridwidth=0.05, gridcolor='#DCDCDC')
fig.update_xaxes(color=cores['roxo'], linecolor='#DCDCDC')
fig.update_traces(texttemplate='%{text:.2s}', textposition="top right",
marker_color=cores['roxo'], line=dict(color=cores['rosa'], width=3))
fig.update_layout(uniformtext_minsize=10, uniformtext_mode='hide',
title='\n Ticket Médio de Vendas', title_x=0.5,
plot_bgcolor=cores['branco'], modebar_activecolor=cores['rosa'],
font_color=cores['preto'], title_font_color=cores['roxo'],
legend_title_font_color=cores['roxo'], yaxis_range=[15,25])
fig.show()
Uma forma de aumentar a participação no mercado e, em consequência disso, elevar o ticket médio, é realizar estudos de benchmarking entre as lojas.
O benchmarking é uma das maneiras de se posicionar no mercado, tomando como referência empresas concorrentes. A lógica é: se um estabelecimento do mesmo ramo consegue atender mais clientes que você, é sinal de que tem um diferencial que atrai as pessoas.
Além do ticket médio mensal, queremos saber qual é o volume médio de vendaspara dotas as lojas. Sendo assim, vamos contar as quantidadse de pedidos de todas as lojas agrupado por mês. Faremos isso com a função pd.groupby() associada a função count().
volume_medio = pedidos.groupby(['InvoiceMonth'], as_index=False).count()[['InvoiceMonth', 'InvoiceNo']]
volume_medio.rename(columns={'InvoiceMonth':'Mês', 'InvoiceNo':'Volume Médio de Vendas'}, inplace=True)
Novamente, substituiremos os valores numéricos da coluna Mês() pelos nomes dos meses.
volume_medio['Mês'] = meses
Logo abaixo, podemos ver a tabela de volume mensal de vendas resultante das operações anteriores.
volume_medio
| Mês | Volume Médio de Vendas | |
|---|---|---|
| 0 | jan | 35147 |
| 1 | fev | 27707 |
| 2 | mar | 36748 |
| 3 | abr | 29916 |
| 4 | mai | 37030 |
| 5 | jun | 36874 |
| 6 | jul | 39518 |
| 7 | ago | 35284 |
| 8 | set | 50226 |
| 9 | out | 60742 |
| 10 | nov | 84711 |
| 11 | dez | 68006 |
Vamos plotar o gráfico para visualizar melhor os volumes de venda e seu comportamento ao longo dos meses. Em caso de dúvidas sobre o código abaixo consulte a Documentação Plotly Express.
fig = px.area(volume_medio, x="Mês", y="Volume Médio de Vendas", text="Volume Médio de Vendas", height=400)
fig.update_yaxes(color=cores['roxo'], showgrid=True,
gridwidth=0.05, gridcolor='#DCDCDC')
fig.update_xaxes(color=cores['roxo'], linecolor='#DCDCDC')
fig.update_traces(texttemplate='%{text:.2s}', textposition="top right",
marker_color=cores['roxo'], line=dict(color=cores['rosa'], width=3))
fig.update_layout(uniformtext_minsize=10, uniformtext_mode='hide',
title='\n Volume Mensal de Vendas em Milhares', title_x=0.5,
plot_bgcolor=cores['branco'], modebar_activecolor=cores['rosa'],
font_color=cores['preto'], title_font_color=cores['roxo'],
legend_title_font_color=cores['verde'], yaxis_range=[0,100000])
fig.show()
Podemos notar no gráfico acima que há um efeito de sazonalidade no volume de vendas, ou seja, períodos em que o volume de vendas varia muito, tanto positivamente quanto negativamente.
Neste cenário a empresa poderia investir em lançamentos de novos produtos nas duas janelas comerciais, ou seja, em março para minizar o efeito da sazonalidade no volume de vendas e em outubro para maximizar o efeito da sazonalidade e garantir produtos diferenciados para o mês de black friday.
Para saber se existe alguma correlação (sentido estatístico) aplicaremos o teste de correlação Spearman.
O teste de correlação de Spearman é semelhante ao de Pearson em termos de significado e interpretação. Entretanto, a utilização e o cálculo são diferentes. Usamos o método de Spearman quando queremos medir a correlação entre variáveis numéricas (lineares ou não) ou entre variáveis qualitativas e quantitativas.
Afinal, esse teste mede a relação monotônica entre duas variáveis. De forma simples, significa medir se X e Y variam juntas, mas não necessariamente em uma taxa constante.
A tabela abaixo explica a intensidade da correlação entre duas váriáveis de acordo com os valores que R pode assumir.
Tendo entendido um pouco sobre a correlação de Spearman, vamos calcular o volume total de itens vendidos por país.
volume_pais = pedidos.groupby('Country', as_index=False).sum()[['Country','Quantity']].sort_values(by='Quantity', ascending=False)
O teste de correlação de Spearman exige que as variável qualitativas sejam ordenadas para que possa ser o coeficiente de correlação (r) possa ser calculado. Portanto, criaremos a coluna CountryNumber() que armazenará um número de acordo com a grandeza do volume total de ítens vendidos por cada país.
country_dict = {}
for i, v in enumerate(volume_pais['Country']):
country_dict[v] = i + 1
volume_pais['CountryNumber'] = [country_dict[volume_pais['Country'][i]] for i in volume_pais.index]
volume_pais.head(3)
| Country | Quantity | CountryNumber | |
|---|---|---|---|
| 36 | United Kingdom | 4263829 | 1 |
| 24 | Netherlands | 200128 | 2 |
| 10 | EIRE | 142637 | 3 |
Neste instante, já podemos aplicar o teste de correlação de Spearman aos dados. Vamos utilizar a função spearmanr() do pacote estatístico scipy.stats para aplicar o teste.
country = volume_pais['CountryNumber']
qtd = volume_pais['Quantity']
r, p_valor = spearmanr(qtd, country)
print(f'Correlação de Spearman {r:0.3}')
print(f'P-valor: {p_valor}')
Correlação de Spearman -1.0 P-valor: 0.0
Com base no resultado acima, podemos assumir que a correlação entre as variáveis País e Volume de Ítens Vendidosé muito forte, logo, estatisticamente, podemos dizer que o volume vendido está correlacionado ao país de origem dos pedidos.
Agora vamos reordenar os dados para plotar o gráfico que nos possibilitará saber o volume de itens vendidos por país.
volume_pais.sort_values(by='Quantity', ascending=True, inplace=True)
fig = px.bar(volume_pais, y='Country', x='Quantity',
text='Quantity', labels={'Country':'País',
'Quantity':'Volume de Vendas'}, orientation='h', height=700,)
fig.update_traces(texttemplate='%{text:.2s}',textposition='outside',
marker_color=cores['rosa'], marker_line=dict(width=0.8, color=cores['roxo']))
fig.update_yaxes(color=cores['roxo'], linecolor=cores['roxo'])
fig.update_xaxes(color=cores['roxo'], linecolor=cores['roxo'])
fig.update_layout(uniformtext_minsize=10, uniformtext_mode='hide',
title='Volume de Vendas por País em Milhões ', title_x=0.5,
plot_bgcolor=cores['branco'], modebar_activecolor=cores['rosa'],
font_color=cores['preto'], title_font_color=cores['roxo'],
legend_title_font_color=cores['verde'])
fig.show()
No gráfico acima podemos facilmente perceber que o país com maior volume de vendas é o Reino Unido. Logo, vale a pena descobrir qual o comportamento de vendas dos produtos neste país.
Começaremos descobrindo qual o item mais vendido no Reino Unido. Dessa forma, vamos filtrar a tabela pedidos, obtendo apenas os pedidos feitos no Reino Unido.
df_reino_unido = pedidos[pedidos['Country'] == 'United Kingdom']
Visualizando as 3 primeiras linhas do conjunto de dados de pedidos feitos no Reino Unido.
df_reino_unido.head(3)
| InvoiceNo | StoreId | StockCode | Description | Quantity | InvoiceDate | UnitPrice | CustomerID | Country | TotalFaturamento | InvoiceMonth | |
|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 536365 | 11 | 85123A | WHITE HANGING HEART T-LIGHT HOLDER | 6 | 2010-12-01 08:26:00 | 2.55 | 17850.0 | United Kingdom | 15.30 | 12 |
| 1 | 536365 | 9 | 71053 | WHITE METAL LANTERN | 6 | 2010-12-01 08:26:00 | 3.39 | 17850.0 | United Kingdom | 20.34 | 12 |
| 2 | 536365 | 17 | 84406B | CREAM CUPID HEARTS COAT HANGER | 8 | 2010-12-01 08:26:00 | 2.75 | 17850.0 | United Kingdom | 22.00 | 12 |
Calculando a o total de itens vendidos por tipo de produto e ordenando do menor para o maior. Vamos armazenar isto em uma tabela temporária temp
temp = df_reino_unido.groupby(['StockCode'], as_index=False).sum()[['StockCode', 'Quantity']].sort_values(by='Quantity', ascending=False)
temp.head(3)
| StockCode | Quantity | |
|---|---|---|
| 1145 | 22197 | 52928 |
| 2995 | 84077 | 48326 |
| 3511 | 85099B | 43167 |
Agora vamos descobrir o valor máximo max() de itens vendidos e fazer um relacionamento pd.merge() entre as tabelas para obtermos além código de estoque do produto, a sua descrição.
temp[temp['Quantity'] == max(temp['Quantity'])].merge(df_reino_unido, how='left', on='StockCode').iloc[0:1][['StockCode','Quantity_x', 'Description' ]]
| StockCode | Quantity_x | Description | |
|---|---|---|---|
| 0 | 22197 | 52928 | SMALL POPCORN HOLDER |
O produto Small Popcorn Holder é o mais vendido no Reino Unido.
Seu código de estoque é 22197.
Seu volume total de vendas é 52928 unidades.

Descobrindo o valor mínimo min() de itens vendidos e fazendo um relacionamento pd.merge() entre as tabelas para obtermos além código de estoque do produto, a sua descrição.
temp[temp['Quantity'] == min(temp['Quantity'])].merge(df_reino_unido, how='left', on='StockCode').iloc[0:1][['StockCode','Quantity_x', 'Description' ]]
| StockCode | Quantity_x | Description | |
|---|---|---|---|
| 0 | 23005 | -14468 | TRAVEL CARD WALLET I LOVE LONDON |
O produto Travel Card Wallet I Love London é o menos vendido no Reino Unido.
Seu código de estoque é 23005.
Seu volume total de vendas é -14468 unidades.

Este produto certamente deveria ser descontinuado, uma vez que possui um valor negativo de quantidades vendidas (provavelmente devoluções) e ocupa espaço em estoque.
Para aprofundar um pouco mais a investigação das vendas do Reino Unido, vamos analisar quantidade de produtos em cada partição da sua curva ABC de vendas para cada loja.
A curva ABC de vendas, trata-se de uma ferramenta que orienta as estratégias comerciais de uma empresa. Ela mostra aos gestores quais produtos ou grupo de clientes devem ser priorizados, uma vez que representam maior potencial de gerar lucro para o negócio.
A curva ABC, então, surge como uma forma de classificar e agrupar produtos e clientes de acordo com o potencial de gerar receita.
Poderíamos calcular a curva ABC de vendas de modo simples, utilizando apenas linguagem Python, mas faremos os cálculos utilizando a linguagem SQL. Abaixo, a instrução SQL para o cálculo. A princípio o tamanho do código pode assustar, mas é necessário fazer algumas subqueries para realizar todas as operações em apenas uma instrução.
query = '''SELECT d3.StoreId,
d3.class_abc,
COUNT(d3.class_abc) AS quantity_abc
FROM (
SELECT d2.StoreId,
d2.StockCode,
d2.total_billing,
d2.grand_total,
d2.perc,
d2.acc_perc,
CASE
WHEN d2.acc_perc <= 80 THEN 'A'
WHEN d2.acc_perc <= 95 THEN 'B'
ELSE 'C'
END class_abc
FROM (
SELECT d1.StoreId,
d1.StockCode,
d1.total_billing,
d1.grand_total,
d1.perc,
SUM(d1.perc) OVER(ORDER BY d1.total_billing DESC) acc_perc
FROM (
SELECT d.StoreId,
d.StockCode,
d.total_billing,
SUM(d.total_billing) OVER() grand_total,
CAST(d.total_billing AS NUMERIC(15,3)) / CAST(SUM(d.total_billing) OVER() AS NUMERIC(15,3)) * 100 perc
FROM (
SELECT StoreId, StockCode, SUM(CAST(Quantity AS FLOAT))* sum(UnitPrice) AS total_billing FROM df_reino_unido
GROUP BY StoreId, StockCode) d) d1) d2)d3 group by d3.StoreId, d3.class_abc ORDER BY d3.StoreId;'''
Utilizaremos o pacote pandasql para manipular o DataFrame pandas por meio da linguagem sql.
df_reino_unido_2 = pd.DataFrame(sqldf(query, globals()))
df_reino_unido_2.head()
| StoreId | class_abc | quantity_abc | |
|---|---|---|---|
| 0 | 1 | A | 123 |
| 1 | 1 | B | 201 |
| 2 | 1 | C | 2724 |
| 3 | 10 | A | 115 |
| 4 | 10 | B | 191 |
A query sql executada nos retornou a tabela acima com as colunas StoreId, class_abc e quantity_abc.
Convertendo o tipo da coluna StoreId para inteiro para que possamos ordenar os valores de acordo com o número da loja
df_reino_unido_2['StoreId'] = df_reino_unido_2['StoreId'].astype(int)
df_reino_unido_2 = df_reino_unido_2.sort_values(by='StoreId', ascending=True)
Atribuindo nomes genéricos para as lojas uma vez que temos apenas os seus ID's.
lojas = ['Loja ' + str(df_reino_unido_2['StoreId'][i]) for i in df_reino_unido_2.index]
df_reino_unido_2['StoreId'] = lojas
Definindo as cores do layout e plotando o gráfico.
cores_2 = ['#3C0877','#232323','#F93D8A',]
fig = px.bar(df_reino_unido_2, y='quantity_abc', x='StoreId',
labels={'quantity_abc':'Quantidade','StoreId':'Lojas'},
orientation='v',color='class_abc', color_discrete_map={'A': cores_2[0],
'B': cores_2[1],
'C':cores_2[2]})
fig.update_yaxes(color=cores['roxo'], linecolor=cores['roxo'])
fig.update_xaxes(color=cores['roxo'], linecolor=cores['roxo'])
fig.update_layout(uniformtext_minsize=7.6, uniformtext_mode='show',
title='''Quantidade de Produtos em Cada Partição da Curva ABC de Vendas <br>
<sup>Agrupado por Loja do Reino Unido</sup>''',
title_x=0.5,
plot_bgcolor=cores['branco'], modebar_activecolor=cores['rosa'],
font_color=cores['preto'], title_font_color=cores['roxo'],
legend_title_font_color='#232323')
fig.show()
Olhando para o gráfico, podemos identificar o princípio de Pareto, em que 80% dos efeitos são devidos a 20% das causas. Podemos ver que a categoria A de produtos tem uma quantidade menor do que todas as outras, mas é responsável por cerca de 80% do faturamento.
Logo as campanhas de marketing deveriam ser direcionadas para impulcionar estes produtos, que lém de conquistar uma fatia maior de market share iriam, consequentemente, elevar os valores do ticket médio mensal.